
#include "../include/TcpConnection.h"
#include "../include/EventLoop.h"
#include "../include/InetAddress.h"

#include <sstream>

namespace wd
{

TcpConnection::TcpConnection(int fd, EventLoop * loop)
: _sock(fd)
, _sockIO(fd)
, _localAddr(getLocalAddr())
, _peerAddr(getPeerAddr())
, _isShutdownWrite(false)
, _loop(loop)
{

}

TcpConnection::~TcpConnection()
{
    printf("~TcpConnection()\n");
}

string TcpConnection::toString() const
{
    std::ostringstream oss;
    oss << "tcp " << _localAddr.ip() << ":" << _localAddr.port()
        << "--> " << _peerAddr.ip() << ":" << _peerAddr.port();
    return oss.str();
}

bool TcpConnection::isClosed() const
{
    char buff[20] = {0};
    return _sockIO.recvPeek(buff, sizeof(buff)) == 0;
}

void TcpConnection::handleNewConnectionCallback()
{
    if(_onConnection) {
        _onConnection(shared_from_this());
    }
}

void TcpConnection::handleMesssageCallback()
{
    if(_onMessage) {
        _onMessage(shared_from_this());
    }
}

void TcpConnection::handleCloseCallback()
{
    if(_onClose) {
        _onClose(shared_from_this());
    }
}

//每一次获取一行数据
string TcpConnection::receive()
{
    char buff[65536] = {0};
    int ret = _sockIO.readline(buff, sizeof(buff));
    return string(buff, ret);
}

void TcpConnection::send(const string & msg)
{
    _sockIO.sendn(msg.c_str(), msg.size());
}
    
void TcpConnection::sendInLoop(const string & msg)
{
    if(_loop) {
        _loop->runInLoop(std::bind(&TcpConnection::send, this, msg));
    }
}

void TcpConnection::shutdown()
{
    if(!_isShutdownWrite) {
        _sock.shutdownWrite();
        _isShutdownWrite = true;
    }
}
   
int TcpConnection::getfd()
{
    return _sock.fd();
}

InetAddress TcpConnection::getLocalAddr()
{
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    socklen_t len = sizeof(addr);
    int ret = getsockname(_sock.fd(), 
                          (struct sockaddr*)&addr, &len);
    if(ret < 0) {
        perror("getsockname");
    }
    return InetAddress(addr);
}
    
InetAddress TcpConnection::getPeerAddr()
{
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    socklen_t len = sizeof(addr);
    int ret = getpeername(_sock.fd(), 
                          (struct sockaddr*)&addr, &len);
    if(ret < 0) {
        perror("getpeername");
    }
    return InetAddress(addr);

}

bool TcpConnection::readPacket(Packet& packet) {
    // 调用底层 SocketIO 的 readPacket 读取并解析 TLV
    int ret = _sockIO.readPacket(packet);
    if (ret != 0) {
        cout << "[TcpConnection::readPacket] 解析 TLV 失败" << endl;
        return false;  // 失败返回 false
    }
    return true;  // 成功返回 true
}
// 私有函数：实际发送 TLV 数据（在 IO 线程执行）
void TcpConnection::sendTLV(TLV& tlv) {
    // 调用 SocketIO::sendn 发送完整 TLV（TLV 缓冲区 + 总长度）
    int sendRet = _sockIO.sendn(
        static_cast<const char*>(tlv.get_tlv_buff()),  // TLV 二进制缓冲区首地址
        tlv.get_total_size()                          // TLV 总长度（4+4+dataLen）
    );
    if (sendRet != tlv.get_total_size()) {
        cout << "[TcpConnection::sendTLV] TLV 发送失败，实际发 " << sendRet << " 字节" << endl;
    } else {
        cout << "[TcpConnection::sendTLV] TLV 发送成功，总长度 " << sendRet << " 字节" << endl;
    }
}

// 公有函数：线程安全的 TLV 发送接口
void TcpConnection::sendInLoop(const TLV& tlv) {
    if (_loop) {  // 确保 EventLoop 有效
        // 将 sendTLV 绑定为任务，提交到 IO 线程执行
        _loop->runInLoop(std::bind(&TcpConnection::sendTLV, this, tlv));
    } else {
        cout << "[TcpConnection::sendInLoop] EventLoop 为空，无法发送 TLV" << endl;
    }
}


}//end of namespace wd
